#include "CyGUIEditBox.h"
#include "CyRoutine.h"
using namespace std;

CyGUIEditBox::FilterList CyGUIEditBox::_filterList;

CyGUIEditBox::CyGUIEditBox(HWND parentHWND, INT id)
{
	_id = id;
	_hwnd = GetDlgItem(parentHWND, id);
	_enterHandler = NULL;
	if (_hwnd == 0)
	{
		CY_THROW("Cannot find the edit box");
	}

	WNDPROC preProc = (WNDPROC) SetWindowLong(_hwnd,
		GWL_WNDPROC, (LONG)_editBoxProc);
	if (preProc == _editBoxProc)
	{
		CY_THROW("This edit box already has a CyGUIEditBox instance");
	}
	_oldProc = preProc;
	CyGUIEditBox::AddFilter(this);
}

CyGUIEditBox::~CyGUIEditBox(void)
{	
	CyGUIEditBox::RemoveFilter(this);

	if (_enterHandler != NULL)
		delete _enterHandler;

	WNDPROC preProc = 
		(WNDPROC) SetWindowLong(_hwnd, GWL_WNDPROC, (LONG)_oldProc);
}

void CyGUIEditBox::SetText(const std::wstring& str)
{
	SetWindowText(_hwnd, str.c_str());
}

wstring& CyGUIEditBox::GetText(wstring& str) const
{
	UINT l = GetWindowTextLength(_hwnd);
	WCHAR* buffer = new WCHAR[l+1];
	GetWindowText(_hwnd, buffer, l+1);
	str = buffer;
	delete []buffer;
	return str;
}

int CyGUIEditBox::GetInt() const
{
	wstring buffer;
	GetText(buffer);
	return CyRoutine::GetInt(buffer);
}

float CyGUIEditBox::GetFloat() const
{
	wstring buffer;
	GetText(buffer);
	return CyRoutine::GetFloat(buffer);
}

double CyGUIEditBox::GetDouble() const
{
	wstring buffer;
	GetText(buffer);
	return CyRoutine::GetDouble(buffer);
}

BOOL CyGUIEditBox::HandleMessage(HWND hWnd,
		UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_KEYUP:
		if(wParam == VK_RETURN)
		{
			if(this->_enterHandler != NULL)
				this->_enterHandler->Do(hWnd, message, wParam, lParam);
			return TRUE;
		}
		break;

	case WM_CHAR:
		if(wParam == VK_RETURN)
			return TRUE;
		break;

	case WM_KEYDOWN:
		if(wParam == VK_RETURN)
			return TRUE;
		break ;
	}

	return FALSE;
}

// static member
void CyGUIEditBox::AddFilter(CyGUIEditBox *filter)
{
	_filterList.push_back(filter);
}

void CyGUIEditBox::RemoveFilter(CyGUIEditBox *filter)
{
	for (FilterList::iterator i = _filterList.begin();
		i != _filterList.end(); i++)
	{
		if (*i == filter)
		{
			_filterList.erase(i);
			return;
		}
	}

	CY_THROW("Cannot find the message filter in filter list");
}

LRESULT CALLBACK _editBoxProc (HWND hwnd,
	UINT message, WPARAM wParam, LPARAM lParam)
{
	BOOL result = FALSE;

	CyGUIEditBox::FilterList::iterator i = CyGUIEditBox::_filterList.begin();
	for (; i != CyGUIEditBox::_filterList.end(); i++)
	{
		if((*i)->_hwnd == hwnd)
		{
			if((*i)->HandleMessage(hwnd, message, wParam, lParam))
				return 0;
			break;
		}
	}

	return CallWindowProc((*i)->_oldProc, hwnd, message, wParam, lParam) ;
}